#ifndef M_MODBUS_COMM_H
#define M_MODBUS_COMM_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <modbus/modbus.h>
#include "common_types.h"

// 配置参数宏定义
#define CONFIG_FILE_PATH "/etc/m_modbus.ini"  // 配置文件路径
#define MAX_REG_NUM 64                          // 最大寄存器组数
#define MAX_COIL_LEN 128                        // 最大线圈数量
#define MAX_DISCRETE_LEN 128                    // 最大离散输入数量
#define MAX_HOLDING_LEN 64                      // 最大保持寄存器数量
#define MAX_INPUT_LEN 64                        // 最大输入寄存器数量
#define RECONNECT_INTERVAL 3                    // 重连间隔（秒）
#define MODBUS_TIMEOUT 1000                     // 通信超时（毫秒）
// 自动检测相关配置
#define MAX_ONLINE_DEVICES 32    // 最大在线设备数
#define DEFAULT_SCAN_START 1     // 默认扫描起始地址（RTU）
#define DEFAULT_SCAN_END 32      // 默认扫描结束地址（RTU）
#define DEFAULT_SCAN_TIMEOUT 500 // 默认扫描超时（毫秒）
#define DEFAULT_RETRY_CNT 2      // 默认重试次数
#define DEFAULT_SCAN_INTERVAL 60 // 默认定时扫描间隔（秒）

// Modbus模式枚举
typedef enum {
    MODBUS_MODE_RTU = 0,
    MODBUS_MODE_TCP,
    MODBUS_MODE_MAX
} modbus_mode_t;

// 寄存器类型枚举
typedef enum {
    REG_TYPE_COIL = 0,          // 线圈（0x01/0x05/0x0F）
    REG_TYPE_DISCRETE_INPUT,    // 离散输入（0x02）
    REG_TYPE_HOLDING,           // 保持寄存器（0x03/0x06/0x10）
    REG_TYPE_INPUT,             // 输入寄存器（0x04）
    REG_TYPE_MAX
} modbus_reg_type_t;

// 读写权限枚举
typedef enum {
    ACCESS_READ_ONLY = 0,
    ACCESS_READ_WRITE,
    ACCESS_MAX
} modbus_access_t;

// 配置结构体
typedef struct {
    modbus_mode_t mode;             // Modbus模式（RTU/TCP）
    // RTU参数
    char serial_dev[32];            // 串口设备（如/dev/ttyS0）
    int baudrate;                   // 波特率
    int data_bits;                  // 数据位
    int stop_bits;                  // 停止位
    char parity;                    // 校验位（N/O/E）
    int slave_addr;                 // 从站地址
    // TCP参数
    char tcp_ip[32];                // TCP从站IP（客户端模式）或监听IP（服务端模式）
    int tcp_port;                   // TCP端口（默认502）
    int is_server;                  // TCP模式：1=服务端，0=客户端
} modbus_config_t;

// 寄存器描述结构体
typedef struct {
    modbus_reg_type_t type;         // 寄存器类型
    uint16_t addr;                  // 起始地址
    uint16_t len;                   // 长度（数量）
    modbus_access_t access;         // 读写权限
    union {
        uint8_t coil[MAX_COIL_LEN];         // 线圈数据（1bit/个）
        uint8_t discrete[MAX_DISCRETE_LEN]; // 离散输入数据（1bit/个）
        uint16_t holding[MAX_HOLDING_LEN];  // 保持寄存器数据（16bit/个）
        uint16_t input[MAX_INPUT_LEN];      // 输入寄存器数据（16bit/个）
    } data;                         // 数据存储
    char desc[64];                  // 描述信息
    // 写回调函数（寄存器被写入时触发）
    void (*write_cb)(modbus_reg_type_t type, uint16_t addr, uint16_t val);
} modbus_register_t;

// 在线设备信息结构体
typedef struct {
    modbus_mode_t mode;         // 设备模式（RTU/TCP）
    union {
        int slave_addr;         // RTU从站地址
        char tcp_ip[32];        // TCP设备IP
    } dev_id;                   // 设备唯一标识
    int tcp_port;               // TCP端口（仅TCP模式）
    time_t last_online;         // 最后在线时间戳
} modbus_online_dev_t;

// 自动检测配置结构体
typedef struct {
    int scan_start;             // 扫描起始地址（RTU）/ IP段起始（TCP，如192.168.1.1）
    int scan_end;               // 扫描结束地址（RTU）/ IP段结束（TCP，如192.168.1.255）
    int scan_timeout;           // 单次扫描超时（毫秒）
    int retry_cnt;              // 重试次数
    int scan_interval;          // 定时扫描间隔（秒，0=关闭定时扫描）
    int scan_running;           // 扫描运行标志（1=正在扫描）
    pthread_t scan_thread;      // 定时扫描线程
} modbus_scan_config_t;

// 连接状态枚举（volatile修饰，防止编译器优化导致读取旧值）
typedef enum {
    CONN_DISCONNECTED = 0,  // 初始状态：未连接/已断开（安全状态）
    CONN_CONNECTING,        // 过渡状态：正在建立连接（不可中断）
    CONN_CONNECTED,         // 稳定状态：连接正常（可通信）
    CONN_RECONNECTING,      // 过渡状态：连接中断，正在重连（不可中断）
    CONN_ABNORMAL           // 异常状态：重连失败，需人工干预/下次扫描重试
} __attribute__((packed)) conn_status_t;  // packed修饰：确保内存对齐，原子读写

// 自动配置相关定义
#define MAX_DEVICE_TEMPLATES 16  // 最大设备配置模板数
#define MAX_REG_TEMPLATE_NUM 32  // 每个模板最大寄存器组数
#define DEVICE_ID_LEN 16         // 设备标识（ID/型号）长度
#define TEMPLATE_FILE_PATH "/etc/modbus_templates.ini"  // 配置模板文件路径

// 设备配置模板（存储不同设备的适配参数）
typedef struct {
    char dev_id[DEVICE_ID_LEN];          // 设备标识（如"MODBUS-DEV-001"，需从设备读取）
    char dev_model[32];                  // 设备型号（描述用）
    modbus_mode_t mode;                  // 适配模式（RTU/TCP）
    // 通信参数（覆盖全局配置，适配不同设备的通信特性）
    int timeout;                         // 通信超时（毫秒）
    int retry_cnt;                       // 重试次数
    // 寄存器映射模板（自动注册）
    modbus_register_t regs[MAX_REG_TEMPLATE_NUM];
    int reg_cnt;                         // 模板中寄存器数量
} modbus_device_template_t;

// 自动连接（连接池）相关定义
#define MAX_CONN_POOL_SIZE 16  // 最大连接数（与在线设备数匹配）
#define HEARTBEAT_INTERVAL 10  // 心跳检测间隔（秒）
#define HEARTBEAT_RETRY 3      // 心跳失败阈值（超过则判定离线）
#define RECONNECT_MAX 5        // 最大重连次数（超过则标记设备异常）


// 连接池节点（管理单个设备的通信上下文和状态）
typedef struct {
    modbus_online_dev_t dev_info;        // 设备基础信息（从在线列表获取）
    modbus_t *ctx;                       // 独立通信上下文（避免设备间冲突）
    modbus_device_template_t *template;  // 适配的配置模板（自动配置结果）
    conn_status_t status;                // 连接状态
    int heartbeat_fail_cnt;              // 心跳失败次数
    int reconnect_cnt;                   // 重连次数
    pthread_mutex_t conn_mutex;          // 连接操作互斥锁
} conn_pool_node_t;

// 连接池管理结构体
typedef struct {
    conn_pool_node_t nodes[MAX_CONN_POOL_SIZE];  // 连接节点数组
    int node_cnt;                                // 已使用节点数
    pthread_mutex_t pool_mutex;                  // 连接池操作互斥锁
    pthread_t heartbeat_thread;                  // 心跳监控线程
    int heartbeat_running;                       // 心跳线程运行标志
} modbus_conn_pool_t;

// 全局上下文结构体
typedef struct {
    modbus_t *ctx;                  // libmodbus上下文
    modbus_config_t config;         // 配置参数
    modbus_register_t regs[MAX_REG_NUM]; // 寄存器列表
    int reg_count;                  // 已注册寄存器数量
    pthread_mutex_t reg_mutex;      // 寄存器访问互斥锁
    int running;                    // 运行标志（1=运行，0=停止）
    int conn_fd;                    // TCP连接句柄（服务端模式）
    modbus_scan_config_t scan_cfg;          // 检测配置
    modbus_online_dev_t online_devs[MAX_ONLINE_DEVICES]; // 在线设备列表
    int online_dev_cnt;                     // 在线设备数量
    pthread_mutex_t scan_mutex;             // 检测相关互斥锁
    modbus_device_template_t templates[MAX_DEVICE_TEMPLATES];  // 设备配置模板
    int template_cnt;                                          // 模板数量
    modbus_conn_pool_t conn_pool;
} m_modbus_ctx_t;

#endif //M_MODBUS_COMM_H
